widget: Don't cache widget paths all the time
authorBenjamin Otte <otte@redhat.com>
Sat, 7 Apr 2012 12:15:35 +0000 (14:15 +0200)
committerBenjamin Otte <otte@redhat.com>
Tue, 17 Apr 2012 06:59:21 +0000 (08:59 +0200)
Add an internal API that allows GtkStyleContext to create a widget path
for the widget and with that bypassing gtk_widget_get_path() and that
  function caching the path.

gtk/gtkbox.c
gtk/gtkcombobox.c
gtk/gtkcontainer.c
gtk/gtkmenu.c
gtk/gtkpathbar.c
gtk/gtkspinbutton.c
gtk/gtkstylecontext.c
gtk/gtktoolbar.c
gtk/gtkwidget.c
gtk/gtkwidgetprivate.h

index 9276a71e6ca5abbd29a75e786dc63c9483fc4c6c..cc0cb8a20c288b9305fcbfecb2512ca630d24389 100644 (file)
@@ -899,7 +899,7 @@ gtk_box_get_path_for_child (GtkContainer *container,
   box = GTK_BOX (container);
   private = box->priv;
 
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+  path = _gtk_widget_create_path (GTK_WIDGET (container));
 
   if (gtk_widget_get_visible (child))
     {
index 0272924b47a1fb8bb0aeb3eac34ce30135e6960e..b83412e5e452d88eb21c174ffdc2428fe4688158 100644 (file)
@@ -1415,7 +1415,7 @@ gtk_combo_box_get_path_for_child (GtkContainer *container,
   GtkWidgetPath *sibling_path;
   int pos;
 
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+  path = _gtk_widget_create_path (GTK_WIDGET (container));
 
   if (gtk_widget_get_visible (child))
     {
index 6253ab79fdf3e9ea5131ec340319fa68573294ea..425eea8c8fdff7e8cf0d4cd997dee3d44058e9e8 100644 (file)
@@ -2338,7 +2338,7 @@ gtk_container_real_get_path_for_child (GtkContainer *container,
   GList *classes;
 
   context = gtk_widget_get_style_context (GTK_WIDGET (container));
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+  path = _gtk_widget_create_path (GTK_WIDGET (container));
 
   /* Copy any permanent classes to the path */
   classes = gtk_style_context_list_classes (context);
index f52d110c0b3df04533515049a7bf9ffad16e7228..af521ad1f10bc6939c86be8898423247358a0fc1 100644 (file)
@@ -3198,7 +3198,7 @@ gtk_menu_get_preferred_width (GtkWidget *widget,
       context = gtk_style_context_new ();
 
       /* Create a GtkCheckMenuItem path, only to query indicator spacing */
-      check_path = gtk_widget_path_copy (gtk_widget_get_path (widget));
+      check_path = _gtk_widget_create_path (widget);
       gtk_widget_path_append_type (check_path, GTK_TYPE_CHECK_MENU_ITEM);
 
       gtk_style_context_set_path (context, check_path);
index fdcd33738455c5570305e8e34367e96f26416525..0cdcde4dee7495895348d311c50c78b31317e64b 100644 (file)
@@ -876,7 +876,7 @@ gtk_path_bar_get_path_for_child (GtkContainer *container,
   GtkPathBar *path_bar = GTK_PATH_BAR (container);
   GtkWidgetPath *path;
 
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (path_bar)));
+  path = _gtk_widget_create_path (GTK_WIDGET (path_bar));
 
   if (gtk_widget_get_visible (child) &&
       gtk_widget_get_child_visible (child))
index 5c7dbc19de7fa2618774f56687c7a80507265e10..f1334c03c689ec57aa1d09cb490e380ec64bc643 100644 (file)
@@ -46,6 +46,7 @@
 #include "gtkstock.h"
 #include "gtktypebuiltins.h"
 #include "gtkwidgetpath.h"
+#include "gtkwidgetprivate.h"
 
 #include "a11y/gtkspinbuttonaccessible.h"
 
@@ -746,7 +747,7 @@ gtk_spin_button_panel_nthchildize_context (GtkSpinButton *spin_button,
    * have to emulate what gtk_container_get_path_for_child() would do
    * for the button panels
    */
-  path = gtk_widget_path_copy (gtk_widget_get_path (widget));
+  path = _gtk_widget_create_path (widget);
   direction = gtk_widget_get_direction (widget);
   siblings_path = gtk_widget_path_new ();
 
index 005115102b5078145e8d6dc5d2b8fee4e5f3544b..103f235df4bc37a4b2ea27af0789c3df58683986 100644 (file)
@@ -745,7 +745,7 @@ create_query_path (GtkStyleContext *context)
   guint i, pos;
 
   priv = context->priv;
-  path = gtk_widget_path_copy (priv->widget ? gtk_widget_get_path (priv->widget) : priv->widget_path);
+  path = priv->widget ? _gtk_widget_create_path (priv->widget) : gtk_widget_path_copy (priv->widget_path);
   pos = gtk_widget_path_length (path) - 1;
 
   info = priv->info_stack->data;
@@ -2068,9 +2068,10 @@ _gtk_style_context_peek_style_property (GtkStyleContext *context,
 
   if (priv->widget || priv->widget_path)
     {
+      GtkWidgetPath *widget_path = priv->widget ? _gtk_widget_create_path (priv->widget) : priv->widget_path;
+
       if (gtk_style_provider_get_style_property (GTK_STYLE_PROVIDER (priv->cascade),
-                                                 priv->widget ? gtk_widget_get_path (priv->widget)
-                                                              : priv->widget_path,
+                                                 widget_path,
                                                  state, pspec, &pcache->value))
         {
           /* Resolve symbolic colors to GdkColor/GdkRGBA */
@@ -2109,8 +2110,14 @@ _gtk_style_context_peek_style_property (GtkStyleContext *context,
               gtk_symbolic_color_unref (color);
             }
 
+          if (priv->widget)
+            gtk_widget_path_free (widget_path);
+
           return &pcache->value;
         }
+
+      if (priv->widget)
+        gtk_widget_path_free (widget_path);
     }
 
   /* not supplied by any provider, revert to default */
index be669008fb18109517c48bd23c8836d270222d15..a83f52ae3940cdf34432848bc291e1f766d3d67b 100644 (file)
@@ -3946,7 +3946,7 @@ gtk_toolbar_get_path_for_child (GtkContainer *container,
   g_list_foreach (children, add_widget_to_path, sibling_path);
   g_list_free (children);
 
-  path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (container)));
+  path = _gtk_widget_create_path (GTK_WIDGET (container));
   if (gtk_widget_get_visible (child))
     {
       vis_index = gtk_toolbar_get_visible_position (toolbar, child);
index d74c94140ee00576a5ce335eaac24aefbc3a9992..3c709ca0520f9e015663000fa1c939627a9b2d42 100644 (file)
@@ -13897,6 +13897,39 @@ gtk_widget_path_append_for_widget (GtkWidgetPath *path,
   return pos;
 }
 
+GtkWidgetPath *
+_gtk_widget_create_path (GtkWidget *widget)
+{
+  GtkWidget *parent;
+
+  parent = widget->priv->parent;
+
+  if (parent)
+    return gtk_container_get_path_for_child (GTK_CONTAINER (parent), widget);
+  else
+    {
+      /* Widget is either toplevel or unparented, treat both
+       * as toplevels style wise, since there are situations
+       * where style properties might be retrieved on that
+       * situation.
+       */
+      GtkWidget *attach_widget = NULL;
+      GtkWidgetPath *result;
+
+      if (GTK_IS_WINDOW (widget))
+        attach_widget = gtk_window_get_attached_to (GTK_WINDOW (widget));
+
+      if (attach_widget != NULL)
+        result = gtk_widget_path_copy (gtk_widget_get_path (attach_widget));
+      else
+        result = gtk_widget_path_new ();
+
+      gtk_widget_path_append_for_widget (result, widget);
+
+      return result;
+    }
+}
+
 /**
  * gtk_widget_get_path:
  * @widget: a #GtkWidget
@@ -13913,33 +13946,7 @@ gtk_widget_get_path (GtkWidget *widget)
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
   if (!widget->priv->path)
-    {
-      GtkWidget *parent;
-
-      parent = widget->priv->parent;
-
-      if (parent)
-        widget->priv->path = gtk_container_get_path_for_child (GTK_CONTAINER (parent), widget);
-      else
-        {
-          /* Widget is either toplevel or unparented, treat both
-           * as toplevels style wise, since there are situations
-           * where style properties might be retrieved on that
-           * situation.
-           */
-          GtkWidget *attach_widget = NULL;
-
-          if (GTK_IS_WINDOW (widget))
-            attach_widget = gtk_window_get_attached_to (GTK_WINDOW (widget));
-
-          if (attach_widget != NULL)
-            widget->priv->path = gtk_widget_path_copy (gtk_widget_get_path (attach_widget));
-          else
-            widget->priv->path = gtk_widget_path_new ();
-    
-          gtk_widget_path_append_for_widget (widget->priv->path, widget);
-        }
-    }
+    widget->priv->path = _gtk_widget_create_path (widget);
 
   return widget->priv->path;
 }
index 5cf44dd529d13c41728f511415fb2f9f42bbfd53..fa5e9b819aa8befdf538ab0f9e9c89300e398b04 100644 (file)
@@ -176,6 +176,7 @@ void              _gtk_widget_set_captured_event_handler (GtkWidget
 gboolean          _gtk_widget_captured_event               (GtkWidget *widget,
                                                             GdkEvent  *event);
 
+GtkWidgetPath *   _gtk_widget_create_path                  (GtkWidget    *widget);
 void              _gtk_widget_invalidate_style_context     (GtkWidget    *widget,
                                                             GtkCssChange  change);
 void              _gtk_widget_style_context_invalidated    (GtkWidget    *widget);